
module lcc {

/** !#zh
工具管理 */
export class Utils {
	/**
	 * 加载资源包
	 * @param path 
	 */
	public static async loadBundle(nameOrUrl:string){
		return new Promise<cc.AssetManager.Bundle>((resolve) => {
			cc.assetManager.loadBundle(nameOrUrl, (err, bundle)=>{
				if (!err && bundle) {
					resolve(bundle);
				} else {
					cc.warn("not found Bundle : %s", nameOrUrl);
					resolve();
				}
			});
		});
	}

	/**
	 * 加载json文件
	 * @param jfile json文件
	 */
	public static async loadJson(jfile:string, bundle:cc.AssetManager.Bundle = cc.resources){
		return new Promise<any>((resolve) => {
			bundle.load(jfile, cc.JsonAsset, (err, data : cc.JsonAsset) => {
				if (!err && data) {
					resolve(data.json);
				} else {
					cc.warn("not found Json : %s in %s", jfile, bundle.name);
					resolve();
				}
			});
		});
	}
	
	/**
	 * 加载音频
	 * @param afile 音频文件
	 */
	public static async loadAudio(afile:string, bundle:cc.AssetManager.Bundle = cc.resources) {
		return new Promise<cc.AudioClip>((resolve) => {
			bundle.load(afile, cc.AudioClip, (err, data : cc.AudioClip) => {
				if (!err && data) {
					resolve(data);
				} else {
					cc.warn("not found AudioClip : %s in %s", afile, bundle.name);
					resolve();
				}
			});
		});
	}
	
	/**
	 * 加载预制件
	 * @param pfile 预制件
	 */
	public static async loadPrefab(pfile:string, bundle:cc.AssetManager.Bundle = cc.resources) {
		return new Promise<cc.Prefab>((resolve) => {
			bundle.load(pfile, cc.Prefab, (err, data : cc.Prefab) => {
				if (!err && data) {
					resolve(data);
				} else {
					cc.warn("not found Prefab : %s in %s", pfile, bundle.name);
					resolve();
				}
			});
		});
	}
	
	/**
	 * 加载精灵帧
	 * @param path 路径
	 */
	public static async loadSpriteFrame(path:string, bundle:cc.AssetManager.Bundle = cc.resources){
		return new Promise<cc.SpriteFrame>((resolve)=>{
			bundle.load(path, cc.SpriteFrame, (err, data : cc.SpriteFrame) => {
				if (!err && data) {
					resolve(data);
				}else{
					cc.warn("not found SpriteFrame : %s in %s", path, bundle.name);
					resolve(null);
				}
			});
		});
	}
	
    /**
     * 加载远程精灵帧
     * @param spfurl 路径
     */
    public static async loadRemoteSpriteFrame(spfurl:string, ext:string = ".png"){
        return new Promise<cc.SpriteFrame>((resolve) => {
            cc.assetManager.loadRemote(spfurl, {ext: ext}, (err, data:cc.Texture2D) => {        
                if (!err && data) {
                    resolve(new cc.SpriteFrame(data));
                }else{
					cc.warn("not found Remote SpriteFrame : %s", spfurl);
                    resolve(null);
                }
            });
        });
	}
	
	/**
	 * 加载ttf字体
	 * @param ttffile 字体文件
	 */
	public static async loadTTFFont(ttffile:string, bundle:cc.AssetManager.Bundle = cc.resources) {
		return new Promise<cc.TTFFont>((resolve) => {
			bundle.load(ttffile, cc.TTFFont, (err, data : cc.TTFFont) => {
				if (!err && data) {
					resolve(data);
				} else {
					cc.warn("not found TTFFont : %s in %s", ttffile, bundle.name);
					resolve();
				}
			});
		});
	}
	
	/**
	 * 获得资源的url
	 * @param path 路径
	 */
	public static async getResUrl(path:string, bundle:cc.AssetManager.Bundle = cc.resources){
		return new Promise<string>((resolve)=>{
			bundle.load(path, (err, data:cc.Asset) => {
				if (!err && data) {
					resolve(data.url);
				}else{
					cc.warn("not found ResUrl : %s in %s", path, bundle.name);
					resolve(null);
				}
			});
		});
	}
	
    /**
     * 格式化字符串
     */
    public static formatString(str:string, ...kwargs:any[]){
        return str.replace(/\$\{([\w\d_:\.]+)\}/g, (k,m) => {
			let value = kwargs[m];
			if(value != null){
				return value;
			}
			return "${" + m + "}";
        });
	}
	
	/**
	 * 日期格式化
	 * @param fmt 格式化字符串
	 * @param date 日期
	 */
	public static formatDate(fmt:string, date:Date) {
		let ret;
		const opt = {
			"Y+": date.getFullYear().toString(),        // 年
			"m+": (date.getMonth() + 1).toString(),     // 月
			"d+": date.getDate().toString(),            // 日
			"H+": date.getHours().toString(),           // 时
			"M+": date.getMinutes().toString(),         // 分
			"S+": date.getSeconds().toString()          // 秒
			// 有其他格式化字符需求可以继续添加，必须转化成字符串
		};
		for (let k in opt) {
			ret = new RegExp("(" + k + ")").exec(fmt);
			if (ret) {
				fmt = fmt.replace(ret[1], (ret[1].length == 1) ? (opt[k]) : (opt[k].padStart(ret[1].length, "0")))
			};
		};
		return fmt;
	}

	/**
	 * 获得随机浮点值
	 * @param min 
	 * @param max 
	 */
	public static getRandFloat(min:number, max:number){
		return Math.random() * (max - min + 1) + min;
	}

	/**
	 * 获得随机整数值
	 * @param min 
	 * @param max 
	 */
	public static getRandInt(min:number, max:number){
		return Math.floor(Math.random() * (max - min + 1)) + min;
	}
	
    /**
     * 数组中随机值
     * @param group 
     */
    public static randomElement(elements:any[]){
        let select = Math.floor(Math.random() * 100) % elements.length;
        return elements[select];
    }

	/**
	 * 通过路径获得值
	 * @param root 根对象
	 * @param path 路径
	 * @param split 分隔符
	 */
	public static getValueByPath(root:any, path:string, split:string = "/"){
		if(path[0] == split){
			path = path.substr(1, path.length-1);
		}
		if(path[path.length - 1] == split){
			path = path.substr(0, path.length-1);
		}
		let value = root;
		for(let n of path.split(split)){
			if(!value){
				return null;
			}
			value = value[n];
		}
		return value;
	}

    /**
     * 随机数组的的几个值
     * @param arr 
     * @param count 
     */
    public static randomArray(arr:any[], count:number) {
        var shuffled = arr.slice(0), i = arr.length, min = i - count, temp, index;
        while (i-- > min) {
            index = Math.floor((i + 1) * Math.random());
            temp = shuffled[index];
            shuffled[index] = shuffled[i];
            shuffled[i] = temp;
        }
        return shuffled.slice(min);
	}
	
	/**
	 * 通过UUID获得资源
	 */
	public static getAssetByUUID<T extends cc.Asset>(uuid:string){
		if(CC_EDITOR){
			return new Promise<T>((resolve)=>{
				cc.assetManager.loadAny([ uuid ], function (err, asset:T) {
					if(!err && asset){
						resolve(asset);
					}else{
						cc.warn("not found asset : %s", uuid);
						resolve(null);
					}
				});
			});
		}
	}
};

}
